#include <queue>
#include "Channel.h"
#include "Timer.h"
#include "flat_hash_map"

namespace xncc {
namespace foundation {
    class TimerChannel final : public Channel
    {
      public:
        explicit TimerChannel(EventLoop* loop);
        ~TimerChannel() override;

        TimerChannel(const TimerChannel&)             = delete;
        TimerChannel(const TimerChannel&&)            = delete;
        TimerChannel& operator=(const TimerChannel&)  = delete;
        TimerChannel& operator=(const TimerChannel&&) = delete;

        ChannelType::value Type() override { return ChannelType::TIMER_CHANNEL; }
        types::timer_id_t  addTimer(types::Task tsk, int64_t when, int64_t interval);
        void               cancel(types::timer_id_t timerId);
        std::size_t        timerSize() { return timers_.size(); }
        void               doTimerFuncs(int64_t now);

      private:
        void        handleRead() override;
        bool        readfd();
        void        addTimerInLoop(const Timer::s_ptr& timer);
        void        cancelInLoop(types::timer_id_t timerId);
        auto        getExpired(int64_t now) -> std::vector<Timer::s_ptr>;
        bool        insert(const Timer::s_ptr& timer);
        static auto howMuchTimeFromNow(int64_t when) -> struct timespec;
        void        resetTimerfd(int64_t expiration);
        void        reset(const std::vector<Timer::s_ptr>& expired, int64_t now);

        ska::flat_hash_map<types::timer_id_t, Timer::s_ptr> timers_;
        std::priority_queue<Timer::s_ptr, std::vector<Timer::s_ptr>, TimerGreator>
                             minHeapTimers_;  // 存放需要触发的定时器
        static constexpr int NOBLOCKPOLLER_TIMER_FD = -2;
    };
}  // namespace foundation
}  // namespace xncc